package com.iceberg.two;

import com.iceberg.two.AlgorithmFrameTwoWays;
import com.iceberg.AlgorithmVisHelper;
import com.iceberg.two.TwoWaysQuickSortData;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;

public class AlgorithmVisualizerTwoWay {

    // TODO: 创建自己的数据
    private int DELAY = 40;
    private TwoWaysQuickSortData data;        // 数据
    private AlgorithmFrameTwoWays frame;    // 视图

    public AlgorithmVisualizerTwoWay(int sceneWidth, int sceneHeight, int N){

        // 初始化数据
        // TODO: 初始化数据
        this.data = new TwoWaysQuickSortData(N, sceneHeight);
        // 初始化视图
        EventQueue.invokeLater(() -> {
            frame = new AlgorithmFrameTwoWays("Welcome", sceneWidth, sceneHeight);
            // TODO: 根据情况决定是否加入键盘鼠标事件监听器
            frame.addKeyListener(new AlgoKeyListener());
            frame.addMouseListener(new AlgoMouseListener());
            new Thread(() -> {
                run();
            }).start();
        });
    }

    // 动画逻辑
    private void run(){
        setData(-1, -1, -1, -1, -1, -1);

        quickSort2Ways(0, data.N()-1);

        setData(-1, -1, -1, -1, -1, -1);
    }

    private void quickSort2Ways(int l, int r){
        if (l > r){
            return;
        }
        if (l == r){
            setData(l, r, l, -1, -1, -1);
            return;
        }
        int p = partition(l, r);
        quickSort2Ways(l, p-1);
        quickSort2Ways(p+1, r);
    }

    private int partition(int l, int r){
        int p = (int)(Math.random()*(r-l+1)) + l;
        setData(l, r, -1, p, -1, -1);

        data.swap(l, p);
        int v = data.get(l);
        int i = l + 1;
        setData(l, r, -1, l, -1, -1);

        int j = r;
        setData(l, r, -1, l, i, j);

        while (true){
            while (i <= r && data.get(i) < v){
                i ++;
                setData(l, r, -1, l, i, j);
            }
            while (j >= l+1 && data.get(j) > v){
                j --;
                setData(l, r, -1, l, i, j);
            }
            if (i > j){
                break;
            }
            data.swap(i, j);
            i++;
            j--;
            setData(l, r, j, -1, -1, -1);
        }
        return j;
    }

    private void setData(int l, int r, int fixedPivot, int curPivot, int curL, int curR){
        data.l = l;
        data.r = r;
        if (fixedPivot != -1)
            data.fixedPivots[fixedPivot] = true;
        data.curL = curL;
        data.curR = curR;
        frame.render(data);
        AlgorithmVisHelper.pause(DELAY);
    }

    // TODO: 根据情况决定是否实现键盘鼠标等交互事件监听器类
    private class AlgoKeyListener extends KeyAdapter{ }
    private class AlgoMouseListener extends MouseAdapter{ }

    public static void main(String[] args) {

        int sceneWidth = 800;
        int sceneHeight = 800;

        // TODO: 根据需要设置其他参数，初始化visualizer
        AlgorithmVisualizerTwoWay visualizer = new AlgorithmVisualizerTwoWay(sceneWidth, sceneHeight, 100);
    }
}
